/*
 * The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License");  you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 * http//www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License for
 * the specific language governing rights and limitations under the License.
 *
 * The Original Code is ART Ontology API (AllegroGraph Implementation).
 *
 * The Initial Developer of the Original Code is University of Roma Tor Vergata.
 * Portions created by University of Roma Tor Vergata are Copyright (C) 2010.
 * All Rights Reserved.
 *
 * ART Ontology API (AllegroGraph Implementation) was developed by the Artificial Intelligence Research Group
 * (art.uniroma2.it) at the University of Roma Tor Vergata
 * Current information about the ART Ontology API (AllegroGraph Implementation) can be obtained at 
 * http//art.uniroma2.it/owlart
 *
 */
package it.uniroma2.art.owlart.agraphimpl.models;

import org.openrdf.model.Resource;
import org.openrdf.model.Statement;
import org.openrdf.repository.Repository;
import org.openrdf.repository.RepositoryException;
import org.openrdf.repository.RepositoryResult;
import org.openrdf.sail.SailException;

import it.uniroma2.art.owlart.exceptions.ModelAccessException;
import it.uniroma2.art.owlart.exceptions.ModelCreationException;
import it.uniroma2.art.owlart.model.ARTNode;
import it.uniroma2.art.owlart.model.ARTResource;
import it.uniroma2.art.owlart.model.ARTURIResource;
import it.uniroma2.art.owlart.model.NodeFilters;
import it.uniroma2.art.owlart.models.BaseRDFTripleModel;
import it.uniroma2.art.owlart.models.RDFSReasoner;
import it.uniroma2.art.owlart.models.TransactionBasedModel;
import it.uniroma2.art.owlart.navigation.ARTStatementIterator;
import it.uniroma2.art.owlart.sesame2impl.models.BaseRDFModelSesame2Impl;
import it.uniroma2.art.owlart.sesame2impl.navigation.Sesame2ARTStatementIteratorImpl;

/**
 * 
 * @author Luca Mastrogiovanni <luca.mastrogiovanni@caspur.it>
 * 
 */
public class BaseRDFModelAllegroGraphImpl extends BaseRDFModelSesame2Impl implements BaseRDFTripleModel, RDFSReasoner, TransactionBasedModel {

	public BaseRDFModelAllegroGraphImpl(Repository repo, boolean rdfsReasoning) throws SailException,
			RepositoryException, ModelCreationException {
		super(repo, rdfsReasoning);
	}

	@Override
	public ARTStatementIterator listStatements(ARTResource subj, ARTURIResource pred, ARTNode obj,
			boolean inferred, ARTResource... graphs) throws ModelAccessException {
		if (inferred) {
			RepositoryResult<Statement> repRes;
			try {

				repRes = repConn.getStatements(ses2artFact.aRTResource2SesameResource(subj),
						ses2artFact.aRTURIResource2SesameURI(pred), ses2artFact
								.aRTNode2SesameValue(obj), inferred, getContexts(false, graphs));
				// TODO (Luca): check if this bug (dated version 4.0.6) has been fixed in last version from Franz
				// l'iplementazione AllegroGraph se inferred=TRUE duplica gli statement...
				// con questa riga si eliminano i duplicati...
				if (inferred)
					repRes.enableDuplicateFilter();
				return new Sesame2ARTStatementIteratorImpl(repRes);
			} catch (RepositoryException e) {
				throw new ModelAccessException(e);
			}
		} else
			return super.listStatements(subj, pred, obj, inferred, graphs);
	}

	private Resource[] getContexts(boolean add, ARTResource... graphs) {

		if (graphs == null)
			throw new IllegalArgumentException();
		Resource[] resContexts = new Resource[graphs.length];
		for (int i = 0; i < graphs.length; i++) {
			if (graphs[i] == null)
				throw new IllegalArgumentException(); // a null value for a contest is not accepted in OWLArt
			// (though in Sesame it means: null-context), null-context (main unnamed graph) in OWLArt must be
			// specified as MAINGRAPH
			else if (graphs[i] == NodeFilters.ANY)
				// if any of the graphs is ANY, then an empty array is sent to Sesame (which interpretes as
				// all graphs when reading/deleting and maingraph when adding triples)
				// TODO could be implemented, when writing, as a special NodeFilter/graphs which always fails
				// the equals
				if (!add)
					return new Resource[0];
				else
					throw new IllegalArgumentException(
							"the ANY Node can be used only when reading/deleting triples from the model, not for writing");
			else if (graphs[i] == NodeFilters.MAINGRAPH)
				resContexts[i] = null; // in Sesame, MAINGRAPH is implemented with null on the graphs
			else {
				resContexts[i] = ses2artFact.aRTResource2SesameResource(graphs[i]);
			}
		}
		return resContexts;
	}

}
